﻿#ifndef __AVIFILE__H_
#define __AVIFILE__H_

#include "fifo_buf.h"
#include "rec_write_base.h"
#include "avi_info.h"
#include "rec_switch_rule.h"

#define AVI_MAX_TRACKS 8


class CAviFileWrite:public CRecWriteBase
{
public:
	CAviFileWrite(int channel = 0);
	~CAviFileWrite();
	virtual int Open(const char * file_name, uint32_t fileIndex, uint32_t fileSize,int64_t startTime = 0,PSTFS_RECINFO_EXTERN pExternInfo = NULL);
	virtual int OpenRepairFile(REC_FILE_INFO & recInfo,uint32_t fileLen,int64_t startTime = 0); //追加写入修复的文件,节省空间.
	virtual int Close();
	virtual int WriteFrame(uchar_t * data_buf, uint32_t data_size);
	virtual int RepairFile(char*  diskName,uint32_t fileIndex,uint64_t fileLBA,uint32_t recSize,int64_t startTime,uint32_t& fileSize,int64_t & endTime);
	int Repair_head_info();
	int RecFullStauts(uint32_t offset ,int64_t time);
	uint32_t GetWritePercent();
protected:
	int AVI_write_frame(char *data, long bytes, int keyframe);
	int AVI_write_audio(char *data, long bytes);
	//写入
	int avi_write_data(char *data, unsigned long length, int audio, int keyframe);
	void AVI_set_video(int width, int height, double fps, char *compressor);
	void AVI_set_audio(int channels, long rate, int bits, int format, long mp3rate);
	int AVI_close();
	int avi_close_output_file();
	int avi_update_header();
	int avi_update_movi_info(uint32_t movi_len);
	int avi_sampsize(int j);
	int avi_add_chunk(uchar_t *tag, unsigned char *data, int length);
	int avi_wirte_index();
	bool IsContextCreateIdx(int frmType, int64_t time);
	int  avi_add_index_entry( unsigned char *tag, long flags, unsigned long pos, unsigned long len);
	int  AnalysisFileInfo(uchar_t * pBuf);
	int  AnalysisAVIData(uint32_t dataPos, uchar_t* pBuf,int dataSize,uint32_t & effSize,vector<STFS_REC_IDX> & vecIdx,uint32_t & detect_cnt);
protected:
	uchar_t * m_AVI_header;

	long   fdes;              /* File descriptor of AVI file */
	long   mode;              /* 0 for reading, 1 for writing */
  
	long   m_width;             /* Width  of a video frame */
	long   m_height;            /* Height of a video frame */
	double m_fps;               /* Frames per second */
	char   m_compressor[8];     /* Type of compressor, 4 bytes + padding for 0 byte */
	char   compressor2[8];     /* Type of compressor, 4 bytes + padding for 0 byte */
	long   video_strn;        /* Video stream number */
	long   m_video_frames;      /* Number of video frames */
	char   video_tag[4];      /* Tag of video data */
	unsigned long max_len;    /* maximum video chunk present */
  
	track_t track[AVI_MAX_TRACKS];  // up to AVI_MAX_TRACKS audio tracks supported
 
	long   m_idx_no;             /* number of index entries actually filled */
	long   m_max_idx;           /* number of index entries actually allocated */
  
	off_t v_codech_off;       /* absolut offset of video codec (strh) info */ 
	off_t v_codecf_off;       /* absolut offset of video codec (strf) info */ 
  
	uchar_t * m_aviIdx;       //AVI索引缓存
	uint64_t  m_aviIdx_bufsz; // AVI索引缓存大小
	video_index_entry *video_index;
  
	off_t last_pos;          /* Position of last frame written */
	unsigned long last_len;          /* Length of last frame written */
	int m_must_use_index;              /* Flag if frames are duplicated */
	off_t m_movi_start;
  
	int m_anum;            // total number of audio tracks 
	int m_aptr;            // current audio working track 
  
	BITMAPINFOHEADER_avilib *bitmap_info_header;
	WAVEFORMATEX_avilib *wave_format_ex[AVI_MAX_TRACKS];
	CRecSwitchRule * m_pRecSwitch;
};

/* AVI_MAX_LEN: The maximum length of an AVI file, we stay a bit below
    the 2GB limit (Remember: 2*10^9 is smaller than 2 GB) */


#ifndef UINT_MAX
#define UINT_MAX        0xffffffff
#endif

#define PAD_EVEN(x) ( ((x)+1) & ~1 )

#define HEADERBYTES 2048
#define FRAME_RATE_SCALE 1000000
#define MAX_INFO_STRLEN 64
#define INFO_LIST

#define AVI_MAX_LEN (UINT_MAX-(1<<20)*16-HEADERBYTES)


#endif

